<script lang="ts" setup >
import { ref, reactive, inject, onBeforeMount } from 'vue'
import axios from '../../plugins/axiosInstance'
import { deleteCD, deleteSingle, uploadMusicAPI, deleteMusicFromCD, getMusicEditInfo, updateMusic, uploadCDApi, getCDEditInfo, updateCD, getCDList, getValidUserMusic, insertMusicToCD } from '@api'
import VuePictureCropper, { cropper } from 'vue-picture-cropper'
import { Music, MusicList, User, popMessage, popMessageKey } from '@/type';
import CommonMusicTable from '@components/Common/CommonMusicTable.vue';
import { useRouter } from 'vue-router';
import { useStore } from '@store/index';
import CommonModel from '@components/CommonModel.vue';
const props = defineProps<{
    editType: 'uploadMusic' | 'editMusic' | 'editCd' | 'uploadCd'
    id: string
}>()
const name = {
    uploadMusic: '上传音乐',
    editMusic: '上传音乐',
    editCd: '上传专辑',
    uploadCd: '上传专辑'
}
const titleName = {
    uploadMusic: '音乐名',
    editMusic: '音乐名',
    editCd: '专辑名',
    uploadCd: '专辑名'
}
const CDList = ref<Music[]>([])
const singerList = ref<User[]>([])
const BASEURL = useStore().getBaseUrl()
const router = useRouter()
// 从服务器获取到的文件
const image = ref()
// 本地获取的音乐文件
const music = ref()
// 标题名
const popMessage = inject(popMessageKey) as popMessage
const editInfo = reactive<Music>({
    musicId: "0",
    duration: 0,
    image: '',
    src: '',
    title: '',
    introduce: '',
})
const editCDInfo = reactive<MusicList>({
    id: "0",
    title: "",
    introduce: "",
    image: "",
})
const musicStyle = ref({
    selectData: [
        { id: 1, title: '华语' },
        { id: 2, title: '流行' },
        { id: 3, title: '摇滚' },
        { id: 4, title: '民谣' },
        { id: 5, title: '电子' },
    ],
    select: '流行'
})
onBeforeMount(() => {
    if (props.editType === 'editMusic') {
        getMusicEditInfo(props.id).then((res) => {
            if (res.data.code === 1) {
                editInfo.musicId = res.data.data.musicId
                editInfo.duration = res.data.data.duration
                editInfo.image = res.data.data.image
                editInfo.title = res.data.data.title
                editInfo.src = res.data.data.src
                editInfo.introduce = res.data.data.introduce
                musicStyle.value.select = res.data.data.style
                axios(`${BASEURL}/common/download?url=image/${editInfo.image}`, {
                    method: 'get',
                    responseType: 'blob',
                }).then((res) => {
                    image.value = URL.createObjectURL(res.data);
                })
            }
        })
    }
    if (props.editType === 'editCd') {
        getCDEditInfo(props.id).then(res => {
            editCDInfo.id = res.data.data.id
            editCDInfo.title = res.data.data.title
            editCDInfo.introduce = res.data.data.introduce
            editCDInfo.image = res.data.data.image
            axios(`${BASEURL}/common/download?url=image/${editCDInfo.image}`, {
                method: 'get',
                responseType: 'blob',
            }).then((res) => {
                image.value = URL.createObjectURL(res.data);
            })
        })
        getCDList(props.id).then(res => {
            if (res.data.code == 1) {
                CDList.value = res.data.data.musicList
                singerList.value = res.data.data.singerList
            }
        })
    }

})
const getEditedImg = () => {
    reviewImage.value = cropper?.getDataURL() as string
}
/**
 * 裁剪后的图片
 */
const reviewImage = ref('')
const persent = ref(0)
const choseFile = (e: any) => {
    let file = e.target.files[0];
    image.value = URL.createObjectURL(file);

}
const choseMusic = (e: any) => {
    let file = e.target.files[0];
    editInfo.src = file.name
    music.value = file
    uploadMusic()
}
const uploadMusic = () => {
    let formdata = new FormData()
    formdata.append('file', music.value as Blob)
    axios({
        url: '/common/upload',
        headers: {
            'Content-Type': 'multipart/form-data',
        },
        transformRequest: [(data: any) => {
            return data
        }],
        params: {
            fileType: 'music',
            format: editInfo.src.split('.')[1]
        },
        onUploadProgress: e => {
            persent.value = e.loaded / (e.total as number) * 100 | 0
            console.log(persent.value);
        },
        method: 'post',
        data: formdata
    }).then(res => {
        if (res.data.code === 1) {
            editInfo.src = res.data.data.split("|")[0],
                editInfo.duration = Math.floor(Number(res.data.data.split("|")[1]))
        }
    }).catch(err => {
        console.log(err);
    })
}
const upload_music = () => {
    const formdata = new FormData()
    cropper?.getBlob().then((res) => {
        formdata.append('file', res as Blob)
        return axios({
            url: `/common/upload`,
            method: 'post',
            headers: {
                "Content-Type": 'multipart/form-data'
            },
            params: {
                fileType: 'image',
                format: res?.type.split('/')[1]
            },
            data: formdata
        }).then((res) => {
            if (res.data.code === 1) {
                editInfo.image = res.data.data
                uploadMusicAPI(editInfo.duration, editInfo.title, editInfo.src, editInfo.image as string, editInfo.introduce as string, musicStyle.value.select).then(res => {
                    if (res.data.code == 1) {
                        router.go(-1)
                        popMessage('上传成功', 'success')
                    }
                })
            } else {
                popMessage("缺少参数", 'error')
            }
        })
    })
}
const upload_cd = () => {
    if (editInfo.title == '') {
        return popMessage("标题不能为空", 'error');
    }
    const formdata = new FormData()
    cropper?.getBlob().then((res) => {
        formdata.append('file', res as Blob)
        if (res == null) {
            return uploadCDApi(editInfo.title, editInfo.image as string, editInfo.introduce as string).then(res => {
                if (res.data.code == 1) {
                    router.go(-1)
                    popMessage('上传成功', 'success')
                }
            })
        }
        axios({
            url: `/common/upload`,
            method: 'post',
            headers: {
                "Content-Type": 'multipart/form-data'
            },
            params: {
                fileType: 'image',
                format: res?.type.split('/')[1]
            },
            data: formdata
        }).then((res) => {
            if (res.data.code === 1) {
                editInfo.image = res.data.data
                uploadCDApi(editInfo.title, editInfo.image as string, editInfo.introduce as string).then(res => {
                    if (res.data.code == 1) {
                        router.go(-1)
                        popMessage('上传成功', 'success')
                    }
                })
            }
        })
    })
}
const uploadNewMusic = () => {
    if (props.editType == 'editMusic' || props.editType == 'uploadMusic') {
        upload_music()
    } else {
        upload_cd()
    }
}
const saveEdit = () => {
    const formdata = new FormData()
    cropper?.getBlob().then((res) => {
        formdata.append('file', res as Blob)
        return axios({
            url: `/common/upload`,
            method: 'post',
            headers: {
                "Content-Type": 'multipart/form-data'
            },
            params: {
                fileType: 'image',
                format: res?.type.split('/')[1]
            },
            data: formdata
        }).then((res) => {
            if (res.data.code === 1) {
                if (props.editType == 'editMusic') {
                    editInfo.image = res.data.data
                    updateMusic(editInfo.musicId, editInfo.duration, editInfo.title, editInfo.src, editInfo.image as string, editInfo.introduce as string, musicStyle.value.select).then(res => {
                        if (res.data.code == 1) {
                            router.go(-1)
                            popMessage('更新成功', 'success')
                        }
                    })
                } else if (props.editType == 'editCd') {
                    editCDInfo.image = res.data.data
                    updateCD(editCDInfo.id as string, editCDInfo.title as string, editCDInfo.image as string, editCDInfo.introduce as string).then(res => {
                        if (res.data.code == 1) {
                            router.go(-1)
                            popMessage('更新成功', 'success')
                        }
                    })
                }
            }
        })
    })
}
const deleteMusic = (id: string) => {
    deleteMusicFromCD(props.id, id).then((res) => {
        if (res.data.code == 1) {
            router.back()
            popMessage("成功删除", 'success')
        }
    })
}
const deleteSingleMusic = () => {
    deleteSingle(props.id).then(res => {
        if (res.data.code == 1) {
            getCDList(props.id).then(res => {
                if (res.data.code == 1) {
                    CDList.value = res.data.data.musicList
                    router.back()
                    popMessage("成功删除", 'success')
                }
            })
        }
    })
}
const removeCD = () => {
    deleteCD(props.id).then((res) => {
        if (res.data.code == 1) {
            router.back()
            popMessage("成功删除", 'success')
        }
    })
}
const musicChoseModel = reactive({
    isOpen: false,
    open: () => {
        getValidUserMusic().then(res => {
            if (res.data.code === 1) {
                musicChoseModel.musicList = res.data.data
                musicChoseModel.clickList = new Array(res.data.data.length).fill(false)
            }
        })
        musicChoseModel.isOpen = true
    },
    close: () => {
        musicChoseModel.isOpen = false
        musicChoseModel.clickList = new Array(musicChoseModel.musicList.length).fill(false)
        musicChoseModel.CDMusicList = []
    },
    musicList: [] as Music[],
    CDMusicList: [] as Music[],
    clickList: [] as boolean[],
    addToCDMusicList: (music: Music, index: number) => {
        musicChoseModel.clickList[index] = true
        for (let i = 0; i < musicChoseModel.CDMusicList.length; i++) {
            if (musicChoseModel.CDMusicList[i].musicId == music.musicId) {
                musicChoseModel.CDMusicList.splice(i, 1)
                musicChoseModel.clickList[index] = false
                return
            }
        }
        musicChoseModel.CDMusicList.push(music)
    },
    dropMusic: (music: Music, index: number) => {
        console.log(music);
        console.log(index);
        for (let i = 0; i < musicChoseModel.musicList.length; i++) {
            if (musicChoseModel.musicList[i].musicId == music.musicId) {
                musicChoseModel.clickList[i] = false
                musicChoseModel.CDMusicList.splice(index, 1)
                return
            }
        }
    },
    save: () => {
        if (musicChoseModel.CDMusicList.length == 0) {
            popMessage('未选择待添加的歌曲', 'error');
        }
        let data = [];
        for (let music of musicChoseModel.CDMusicList) {
            data.push({ musicId: music.musicId, musicListId: props.id })
        }
        let json = JSON.stringify(data)
        insertMusicToCD(json).then(res => {
            if (res.data.code == 1) {
                popMessage('成功保存', 'success');
                getCDList(props.id).then(res => {
                    if (res.data.code == 1) {
                        CDList.value = res.data.data.musicList
                        singerList.value = res.data.data.singerList
                    }
                })
                musicChoseModel.close()
            }
        })
    },

})
</script>
<template>
    <input @change="choseFile" type="file" id="image" accept="image/png, image/jpeg" style="display: none;" />
    <input @change="choseMusic" type="file" id="music" accept="audio/*" style="display: none;">
    <div class="container">
        <template v-if="props.editType == 'uploadMusic' || props.editType == 'editMusic'">
            <div class="uploadMusic">
                <label v-if="persent < 100" for="music">
                    <a class="uploadBtn">
                        <span style="color: white;font-size: 14px;margin: auto;">上传音乐</span>
                    </a>
                </label>
                <a v-else class="uploadBtn">
                    <span style="color: white;font-size: 14px;margin: auto;">上传成功</span>
                </a>

            </div>
            <div class="progress">
                <div class="progressBar" :style="{ width: persent + '%' }">
                    <span :style="{ marginLeft: persent * 600 / 100 + 'px' }" class="percent">{{ persent + '%' }}</span>
                </div>
            </div>
        </template>

        <div class="image">
            <span class="text">封面</span>
            <div class="uploadImage">
                <div class="review">
                    <img :src="reviewImage" style="height: 80px;">
                    <div class="mask">封面预览</div>
                </div>
                <VuePictureCropper class="imagePic" :box-style="{
                    width: '200px',
                    height: '200px',
                }" :img="image" :options="{ viewMode: 1, aspectRatio: 1 / 1 }" @ready="getEditedImg"
                    @cropmove="getEditedImg" @zoom="getEditedImg" />
                <label for="image" class="mask_1">点击选择封面</label>
            </div>
        </div>
        <div class="title">
            <span class="text">{{ titleName[props.editType] }}</span>
            <input v-if="props.editType != 'editCd'" v-model="editInfo.title" class="titleInput" type="text">
            <input v-else v-model="editCDInfo.title" class="titleInput" type="text">
            <span class="validSize">
                {{ editInfo.title.length }}/{{ 60 }}
            </span>
        </div>
        <div class="style" v-if="props.editType == 'uploadMusic' || props.editType == 'editMusic'">
            <span class="text">音乐类型</span>
            <select v-model="musicStyle.select" id="style" class="styles" name="styles">
                <option v-for="option in musicStyle.selectData" :value="option.title">{{ option.title }}</option>
            </select>
        </div>
        <div class="intro">
            <span class="text">简介</span>
            <template v-if="props.editType != 'editCd'">
                <textarea v-model="editInfo.introduce" class="introInput" type="text" />
                <span class="validSize">
                    {{ editInfo.introduce?.length }}/{{ 500 }}
                </span>
            </template>
            <template v-else>
                <textarea v-model="editCDInfo.introduce" class="introInput" type="text" />
                <span class="validSize">
                    {{ editCDInfo.introduce?.length }}/{{ 500 }}
                </span>
            </template>
        </div>
        <div v-if="props.editType == 'editCd'">
            <a @click="musicChoseModel.open" class="chose uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">添加单曲</span>
            </a>
        </div>
        <div v-if="props.editType == 'editCd'">
            <CommonMusicTable :delete="deleteMusic" type-id="cd" model="cd" :music-list="CDList" :singer="singerList"
                :my-music="true" :page-size="999" />
        </div>
        <div v-if="props.editType == 'uploadMusic' || props.editType == 'uploadCd'" class="save">
            <a @click="uploadNewMusic" class="uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">{{ name[props.editType] }}</span>
            </a>
            <a @click="router.go(-1)" class="uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">返回</span>
            </a>
        </div>
        <div v-else-if="props.editType == 'editMusic' || props.editType == 'editCd'" class="save">
            <a @click="saveEdit" class="uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">更新</span>
            </a>
            <a @click="router.go(-1)" class="uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">返回</span>
            </a>
            <a v-if="props.editType == 'editMusic'" @click="deleteSingleMusic" class="uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">删除单曲</span>
            </a>
            <a v-if="props.editType == 'editCd'" @click="removeCD" class="uploadBtn">
                <span style="color: white;font-size: 14px;margin: auto;">删除专辑</span>
            </a>
        </div>

    </div>
    <CommonModel title="添加单曲" :isOpen="musicChoseModel.isOpen" :close="musicChoseModel.close" height="400" width="600">
        <div class="model">
            <div class="top">
                <div class="left">
                    <ul class="music">
                        <li @click="musicChoseModel.addToCDMusicList(music, index)" class="item"
                            v-for="music, index of musicChoseModel.musicList">
                            <input v-model="musicChoseModel.clickList[index]" class="check" type="checkbox">
                            <h3 class="musicTitle">{{ music.title }}</h3>
                        </li>
                    </ul>
                    <img style="width: 20px;" src="../../assets/arrowRight.svg">
                    <ul class="music">
                        <li style="justify-content: space-between;" class="item"
                            v-for="music, index of musicChoseModel.CDMusicList">
                            <h3 style="margin-left: 20px;" class="musicTitle">{{ music.title }}</h3>
                            <img @click="musicChoseModel.dropMusic(music, index)" style="width: 25px;margin-right: 20px;"
                                src="../../assets/trash-999.svg" alt="">
                        </li>
                    </ul>
                </div>
            </div>
            <div class="bottom">
                <a @click="musicChoseModel.save" class="uploadBtn">
                    <span style="color: white;font-size: 14px;margin: auto;">保存</span>
                </a>
                <a @click="musicChoseModel.close" class="uploadBtn">
                    <span style="color: white;font-size: 14px;margin: auto;">返回</span>
                </a>

            </div>

        </div>
    </CommonModel>
</template>
<style scoped lang="css">
.style {
    margin-top: 20px;
}

.style .text {
    line-height: 25px;
    margin-right: 30px;
    border-radius: 5px;
    width: 66px;
    display: inline-block;
}

.styles {
    display: inline-block;
    width: 80px;
    height: 22px;
    position: relative;
    vertical-align: middle;
    padding: 0;
    overflow: hidden;
    background-color: #fff;
    color: #555;
    border: 1px solid #aaa;
    text-shadow: none;
    border-radius: 4px;
    transition: box-shadow 0.25s ease;
    z-index: 2;
    padding-left: 15px;
}

.styles:hover {
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}

.styles:before {
    content: "";
    position: absolute;
    width: 0;
    height: 0;
    border: 10px solid transparent;
    border-top-color: #ccc;
    top: 14px;
    right: 10px;
    cursor: pointer;
    z-index: -2;
}

.styles select {
    cursor: pointer;
    padding: 10px;
    width: 100%;
    border: none;
    background: transparent;
    background-image: none;
}

.styles select:focus {
    outline: none;
}

.bottom {
    display: flex;
    justify-content: center;
}

.check {
    margin-left: 20px;
}

.music .musicTitle {
    margin-left: 20px;
}

.music .item {
    list-style-type: none;
    display: flex;
    border-bottom: 1px solid #ededed;
}

.left {
    display: flex;
    justify-content: space-between;
    box-sizing: border-box;
}

.left .music {
    padding-left: 0;
    border: 1px solid #ededed;
    flex: 1;
    height: 251px;
    overflow: scroll;
}

.model {
    height: 100%;
    padding: 0 20px;
}

.chose {
    margin-top: 40px;
    margin-bottom: 20px;
}

.save {
    margin-top: 100px;
    margin-bottom: 50px;
}

.percent {
    font-size: 14px;
    color: white;
}

.progressBar {
    background-color: var(--blue-style);
    border-radius: 50px;
    height: 100%;
}

.progress {
    width: 100%;
    height: 20px;
    background-color: rgb(235, 238, 245);
    margin-bottom: 20px;
    border-radius: 50px;
}

.uploadBtn {
    background-color: var(--blue-style);
    display: inline-flex;
    align-items: center;
    padding: 1px 1px 1px 1px;
    border-radius: 5px 5px 5px 5px;
    height: 30px;
    width: 90px;
    border-right: 2px solid #4483bf;
    cursor: pointer;
    box-sizing: border-box;
    margin-right: 20px;
}

.uploadBtn:hover {
    background-color: var(--blue-style-hover);
}

.uploadMusic {
    width: 100%;
    height: 180px;
    border: 2px dashed #999;
    margin-bottom: 10px;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
}

.intro .validSize {
    bottom: 0;
}

.validSize {
    position: absolute;
    right: 10px;
    text-align: center;
    line-height: 31px;
    color: #999;
}

.introInput {
    width: 562px;
    height: 186px;
    resize: none;
}

.intro {
    display: flex;
    margin-top: 30px;
    position: relative;

}

.intro .text,
.title .text {
    line-height: 25px;
    margin-right: 30px;
    border-radius: 5px;
    width: 66px;
    display: inline-block;
}

.titleInput::after {
    content: attr(data-content);
}

.titleInput {
    height: 25px;
    outline: none;
    flex: 1;
}

.title {
    margin-top: 20px;
    display: flex;
    position: relative;
}

.imagePic {
    border: 1px solid #ededed;
    border-radius: 5px;
}

.review {
    position: relative;
    width: 80px;
    border: 1px solid #ededed;
    border-radius: 5px;
    margin-right: 40px;
}

.review .mask {
    position: absolute;
    width: 80px;
    bottom: 0;
}

.image .text {
    margin-right: 50px;
}

.uploadImage .mask_1 {
    position: absolute;
    bottom: 0;
    right: 0;
    text-align: center;
    width: 200px;
    background-color: rgba(0, 0, 0, 0.1);

}

.uploadImage {
    text-align: center;
    display: flex;
    position: relative;
    justify-items: center;
    align-items: center;
}


.container {
    display: flex;
    margin-top: 60px;
    flex-direction: column;
}

.image {
    display: flex;
    justify-self: center;
    align-items: center;
}
</style>